import { PlatformType as PlatformEnum, DeviceInfo, PerformanceData } from '../types';

// 声明全局变量类型
declare const wx: any;
declare const my: any;

// 移除全局声明，改为使用类型断言或接口
interface UniAPI {
  getSystemInfo: (options: {
    success?: (res: any) => void;
    fail?: (err: any) => void;
  }) => void;
  getNetworkType: (options: {
    success?: (res: { networkType: string }) => void;
    fail?: (err: any) => void;
  }) => void;
  request: (options: any) => void;
  getStorageSync: (key: string) => any;
  setStorageSync: (key: string, value: any) => void;
  removeStorageSync: (key: string) => void;
  switchTab: (options: any) => any;
  navigateTo: (options: any) => any;
  redirectTo: (options: any) => any;
  onError?: (callback: (error: string) => void) => void; // 添加onError方法
}

// 使用类型断言来访问 uni
const getUni = (): UniAPI => (globalThis as any).uni;

export class PlatformAdapter {
  private platformType: PlatformEnum;
  private isInitialized: boolean = false;

  constructor(forcePlatform?: PlatformEnum) {
    this.platformType = forcePlatform || this.detectPlatform();
  }

  /**
   * 初始化平台适配器
   */
  async init(): Promise<void> {
    if (this.isInitialized) {
      return;
    }

    try {
      // 设置错误处理器
      this.setupErrorHandlers();
      
      // 可以在这里添加其他初始化逻辑
      this.isInitialized = true;
      
      console.log('[PlatformAdapter] 初始化成功');
    } catch (error) {
      console.error('[PlatformAdapter] 初始化失败:', error);
      throw error; // 重新抛出错误
    }
  }

  detectPlatform(): PlatformEnum {
    // 如果用户手动指定了平台，这个方法基本不会被调用
    // 但保留作为备用方案
    
    // #ifdef H5
    return PlatformEnum.H5;
    // #endif
    
    // #ifdef MP-WEIXIN
    return PlatformEnum.MpWeixin;
    // #endif
    
    // #ifdef APP-PLUS
    return PlatformEnum.App;
    // #endif
    
    // 简化的运行时检测
    console.warn('[PlatformAdapter] 建议在SDK初始化时手动指定platform参数');
    
    if (typeof window !== 'undefined' && typeof document !== 'undefined') {
      return PlatformEnum.H5;
    }
    
    if (typeof globalThis !== 'undefined' && (globalThis as any).uni) {
      return PlatformEnum.App;
    }
    
    return PlatformEnum.H5;
  }

  getPlatformType(): PlatformEnum {
    return this.platformType;
  }

  async getDeviceInfo(): Promise<any> {
    if (this.platformType === PlatformEnum.H5) {
      // H5 环境 - 同时获取设备信息和网络信息
      const networkInfo = await this.getNetworkType();
      return {
        platform: 'h5',
        system: navigator.userAgent,
        version: '1.0.0',
        SDKVersion: '2.0.0',
        networkType: networkInfo.networkType
      };
    } else {
      // 小程序或 App 环境
      try {
        const uni = getUni();
        
        // 获取系统信息
        const systemInfo: any = await new Promise((sysResolve, sysReject) => {
          uni.getSystemInfo({
            success: (res: any) => sysResolve(res),
            fail: (err: any) => sysReject(err)
          });
        });
        
        // 获取网络信息
        const networkInfo: any = await new Promise((netResolve, netReject) => {
          uni.getNetworkType({
            success: (res: any) => netResolve(res),
            fail: (err: any) => netReject(err)
          });
        });
        
        // 合并系统信息和网络信息
        return {
          ...systemInfo,
          ...networkInfo
        };
      } catch (error) {
        throw error;
      }
    }
  }

  getSystemInfo(): Promise<any> {
    return new Promise((resolve, reject) => {
      if (this.platformType === PlatformEnum.H5) {
        // H5 环境下的系统信息
        resolve({
          platform: 'h5',
          system: navigator.userAgent,
          version: '1.0.0',
          screenWidth: window.screen.width,
          screenHeight: window.screen.height,
          windowWidth: window.innerWidth,
          windowHeight: window.innerHeight
        });
      } else {
        // 小程序或 App 环境
        const uni = getUni();
        uni.getSystemInfo({
          success: (res: any) => resolve(res),
          fail: (err: any) => reject(err)
        });
      }
    });
  }

  getNetworkType(): Promise<{ networkType: string }> {
    return new Promise((resolve, reject) => {
      if (this.platformType === PlatformEnum.H5) {
        // H5 环境下的网络类型检测
        const connection = (navigator as any).connection || (navigator as any).mozConnection || (navigator as any).webkitConnection;
        if (connection) {
          resolve({ networkType: connection.effectiveType || 'unknown' });
        } else {
          resolve({ networkType: 'unknown' });
        }
      } else {
        // 小程序或 App 环境
        const uni = getUni();
        uni.getNetworkType({
          success: (res: { networkType: string }) => resolve(res),
          fail: (err: any) => reject(err)
        });
      }
    });
  }

  /**
   * 获取性能数据
   */
  async getPerformanceData(): Promise<PerformanceData> {
    const performanceData: PerformanceData = {
      memoryUsage: 0,
      loadTime: 0,
      renderTime: 0,
      networkLatency: 0
    };
  
    try {
      if (this.platformType === PlatformEnum.H5) {
        // H5 环境的性能数据
        if (typeof window !== 'undefined' && 'performance' in window) {
          const navigation = performance.getEntriesByType('navigation')[0] as PerformanceNavigationTiming;
          if (navigation) {
            performanceData.loadTime = navigation.loadEventEnd - navigation.loadEventStart;
            performanceData.renderTime = navigation.domContentLoadedEventEnd - navigation.domContentLoadedEventStart;
          }
  
          // 内存信息（如果支持）
          if ('memory' in performance) {
            const memory = (performance as any).memory;
            performanceData.memoryUsage = memory.usedJSHeapSize || 0;
          }
        }
  
        // 网络延迟（仅H5环境支持）
        if (typeof navigator !== 'undefined') {
          const connection = (navigator as any).connection || (navigator as any).mozConnection || (navigator as any).webkitConnection;
          if (connection && connection.rtt) {
            performanceData.networkLatency = connection.rtt;
          }
        }
      } else {
        // App/小程序环境 - 使用uni API获取网络信息
        try {
          const uni = getUni();
          const networkInfo = await new Promise<any>((resolve, reject) => {
            uni.getNetworkType({
              success: (res: any) => resolve(res),
              fail: (err: any) => reject(err)
            });
          });
          
          // 根据网络类型估算延迟（因为app环境无法直接获取RTT）
          const networkLatencyMap: Record<string, number> = {
            'wifi': 20,
            '4g': 50,
            '3g': 100,
            '2g': 300,
            'none': 0,
            'unknown': 50
          };
          
          performanceData.networkLatency = networkLatencyMap[networkInfo.networkType] || 50;
        } catch (error) {
          console.warn('[PlatformAdapter] App环境获取网络信息失败:', error);
          // 使用默认值
          performanceData.networkLatency = 50;
        }
      }
    } catch (error) {
      console.warn('[PlatformAdapter] 获取性能数据失败:', error);
    }
  
    return performanceData;
  }

  setupErrorHandlers(callback?: (error: any, info?: any) => void): void {
    if (this.platformType === PlatformEnum.H5) {
      // H5 环境的错误处理 - 添加安全检查
      if (typeof window !== 'undefined') {
        window.addEventListener('error', (event) => {
          console.error('Global error:', event.error);
          if (callback) {
            callback(event.error, { type: 'javascript', event });
          }
        });
        
        window.addEventListener('unhandledrejection', (event) => {
          console.error('Unhandled promise rejection:', event.reason);
          if (callback) {
            callback(event.reason, { type: 'promise', event });
          }
        });
      }
    } else {
      // 小程序或 App 环境的错误处理
      try {
        const uni = getUni();
        // App环境可以使用uni的错误监听 - 添加安全检查
        if (uni && uni.onError && typeof uni.onError === 'function') {
          uni.onError((error: string) => {
            console.error('App error:', error);
            if (callback) {
              callback(new Error(error), { type: 'app', source: 'uni.onError' });
            }
          });
        }
      } catch (error) {
        console.warn('[PlatformAdapter] App环境错误处理设置失败:', error);
      }
    }
  }
}

export type PlatformType = PlatformEnum;